module Pedido (Pedido, nuevoP, numeroP, atendioP, combosP, dificultadP, agregarComboP, anularComboP, cambiarBebidaComboP)
	where

import Tipos
import Combo

data Pedido = P Int Empleado | AgregarCombo Combo Pedido deriving (Show,Eq)

nuevoP :: Int -> Empleado -> [Combo] -> Pedido
nuevoP n e [] = P n e
nuevoP n e (c:cs) = AgregarCombo c (nuevoP n e cs)

numeroP :: Pedido -> Int
numeroP (P n e) = n 
numeroP (AgregarCombo c p) = numeroP p 

atendioP :: Pedido -> Empleado
atendioP (P n e) = e
atendioP (AgregarCombo c p) = atendioP p

combosP :: Pedido -> [Combo]
combosP (P n e) = []
combosP (AgregarCombo c p)= c: (combosP p)

dificultadP :: Pedido -> Energia
dificultadP (P n e) = 0
dificultadP (AgregarCombo c p)= (dificultadC c) + (dificultadP p)

agregarComboP :: Pedido -> Combo -> Pedido
agregarComboP (P n e) c = (AgregarCombo c (P n e))
agregarComboP (AgregarCombo cs p) c = AgregarCombo cs (agregarComboP p c)

anularComboP :: Pedido -> Int -> Pedido
anularComboP ped i = anulacion ped ped i

--aux
anulacion :: Pedido -> Pedido -> Int -> Pedido
anulacion (P n e) _ _ = (P n e)
anulacion (AgregarCombo c p) ped i 
				|posicion (AgregarCombo c p) ped == i = p
				|otherwise = AgregarCombo c (anulacion p ped i)

--aux
posicion :: Pedido -> Pedido -> Int
posicion (AgregarCombo c (P n e)) ped = totalDeCombos ped - 1
posicion (AgregarCombo c p) ped = posicion p ped - 1

--aux
totalDeCombos :: Pedido -> Int
totalDeCombos p = length (combosP p)


cambiarBebidaComboP :: Pedido -> Bebida -> Int -> Pedido
cambiarBebidaComboP ped beb i = cambioDeBebida ped ped beb i

--aux
cambioDeBebida :: Pedido -> Pedido -> Bebida -> Int -> Pedido
cambioDeBebida (P n e) ped beb i = (P n e)
cambioDeBebida (AgregarCombo c p) ped b i 
					|posicion (AgregarCombo c p) ped == i = (AgregarCombo (cambiarBebida c b) p)
					|otherwise = AgregarCombo c (cambioDeBebida p ped b i)

--aux					
cambiarBebida :: Combo -> Bebida -> Combo
cambiarBebida c b1  = nuevoC b1 (sandwichC c) (dificultadC c) 					

cambiarSanguche :: Combo -> Hamburguesa -> Combo
cambiarSanguche c h1 = nuevoC (bebidaC c) h1 (dificultadC c)

{-
--elMezcladitoP :: Pedido -> Pedido
--elMezladitoP (AgregarCombo c (P n e)) = (AgregarCombo c (P n e))
--elMezcladitoP (AgregarCombo c p)
--				| todasBebidasDistintas
				

--aux				
seRepiteC :: Combo -> Pedido -> Bool
seRepiteC combo (P n e) = False
seRepiteC combo (AgregarCombo c p) = (cantAparicionesC combo 0 (AgregarCombo c p))>1
-}
--Aux, no se exporta
cantAparicionesC :: Combo -> Pedido -> Int
cantAparicionesC _ (P n e) = 0
cantAparicionesC combo (AgregarCombo c p)
		|(sandwichC combo == sandwichC c && bebidaC combo == bebidaC c) = 1 + cantAparicionesC combo p
		|otherwise = cantAparicionesC combo p				


elMezcladitoP :: Pedido -> Pedido
elMezcladitoP (AgregarCombo combo pedido) = elMezcladito' (AgregarCombo combo pedido) (AgregarCombo combo pedido) (P (numeroP pedido) (atendioP pedido))

elMezcladito' :: Pedido -> Pedido -> Pedido -> Pedido
elMezcladito' (P n e) mismoPedido loQueSeAgrego = (P n e)
elMezcladito' (AgregarCombo combo pedido) mismoPedido loQueSeAgrego
{-aca en vez de mismoPedido, si uso (AgregarCombo com pedido) me anda para varios casos-}	|seRepiteC combo mismoPedido = elMezcladito' (AgregarCombo (cambiarLoNecesario (AgregarCombo combo pedido) (AgregarCombo combo pedido) loQueSeAgrego (primerasApariciones (bebidasDelPedido mismoPedido)) (primerasApariciones (sanguchesDelPedido mismoPedido)) mismoPedido) pedido) mismoPedido loQueSeAgrego
	|otherwise = (AgregarCombo combo (elMezcladito' pedido mismoPedido (agregarComboP loQueSeAgrego combo)))
--	where bebidasPedidoOriginal = (primerasApariciones (bebidasDelPedido mismoPedido))
	--sanguchesPedidoOriginal = (primerasApariciones (sanguchesDelPedido mismoPedido))

cambiarLoNecesario :: Pedido -> Pedido -> Pedido ->[Bebida] -> [Hamburguesa] -> Pedido ->  Combo
cambiarLoNecesario (AgregarCombo c1 p1) ped2 loQueSeAgrego (b:bs) (h:hs) pedido
	|(seRepiteC (cambiarBebida c1 b) pedido) || (seRepiteC (cambiarBebida c1 b) loQueSeAgrego) = cambiarLoNecesario (AgregarCombo c1 p1) ped2 loQueSeAgrego bs (h:hs) pedido 
	|otherwise = cambiarBebida c1 b
cambiarLoNecesario ped (AgregarCombo c2 p2) loQueSeAgrego [] (h:hs) pedido
	|(seRepiteC (cambiarSanguche c2 h) pedido) || (seRepiteC (cambiarSanguche c2 h) loQueSeAgrego) = cambiarLoNecesario ped (AgregarCombo c2 p2) loQueSeAgrego [] hs pedido
	|otherwise = cambiarSanguche c2 h
--	where 	fueAgregadoAntesH = (seRepiteC (cambiarSanguche c2 h) loQueSeAgrego)
--		fueAgregadoAntesB = (seRepiteC (cambiarBebida c1 b) loQueSeAgrego)


-- No me funcionan los where xD ver al final

--elMezcladitoP (AgregarCombo (nuevoC PestiCola McPato 1) (AgregarCombo (nuevoC PestiCola McPato 2) (AgregarCombo (nuevoC AguaConGags McGyver 3) (AgregarCombo (nuevoC PestiCola McPato 4) (P 11 "A"))))) 
--Este caso me caga, porque me parece que no estoy acumulando los combos en "loQueSeAgrego" entonces se repite Agua Pato

-- elMezcladitoP (AgregarCombo (nuevoC PestiCola McPato 1) (AgregarCombo (nuevoC PestiCola McPato 2) (AgregarCombo (nuevoC AguaConGags McGyver 3) (AgregarCombo (nuevoC PestiCola BigMacabra 4) (P 11 "A"))))) Funciona.

-- elMezcladitoP (AgregarCombo (nuevoC PestiCola BigMacabra 1) (AgregarCombo (nuevoC PestiCola McPato 2) (AgregarCombo (nuevoC AguaConGags McGyver 3) (AgregarCombo (nuevoC PestiCola McPato 4) (P 11 "A"))))) Funciona.

-- elMezcladitoP (AgregarCombo (nuevoC PestiCola McPato 1) (AgregarCombo (nuevoC PestiCola McGyver 2) (AgregarCombo (nuevoC AguaConGags McGyver 3) (AgregarCombo (nuevoC PestiCola McPato 4) (P 11 "A"))))) Funciona.

-- elMezcladitoP (AgregarCombo (nuevoC PestiCola McPato 1) (AgregarCombo (nuevoC PestiCola McGyver 2) (AgregarCombo (nuevoC AguaConGags McGyver 3) (AgregarCombo (nuevoC PestiCola McPato 4) (AgregarCombo (nuevoC AguaConGags McGyver 5) (P 11 "A")))))) Este tambien me caga por la misma razon que el primero creo.
--Devuelve: AgregarCombo (C AguaConGags McPato 1) (AgregarCombo (C PestiCola McGyver 2) (AgregarCombo (C PestiCola McGyver 3) (AgregarCombo (C PestiCola McPato 4) (AgregarCombo (C AguaConGags McGyver 5) (P 11 "A")))))


bebidasDelPedido :: Pedido -> [Bebida]
bebidasDelPedido (P n e) = []
bebidasDelPedido (AgregarCombo c p) = bebidaC c : bebidasDelPedido p

sanguchesDelPedido :: Pedido -> [Hamburguesa]
sanguchesDelPedido (P n e) = []
sanguchesDelPedido (AgregarCombo c p) = sandwichC c : sanguchesDelPedido p

seRepiteC :: Combo -> Pedido -> Bool
seRepiteC combo (P n e) = False
seRepiteC combo (AgregarCombo c p) = (cantAparicionesC combo (AgregarCombo c p))>1

--Aux
primerasApariciones :: Eq a => [a] -> [a]
primerasApariciones lista = primerasApariciones' [] lista

--Aux
primerasApariciones' :: Eq a => [a] -> [a] -> [a]
primerasApariciones' xs [] = xs
primerasApariciones' xs (y:ys)
	|elem y xs == False = primerasApariciones' (xs++[y]) ys
	|otherwise = primerasApariciones' xs ys

{- El problema es que tengo que ver que cuando cambio de nuevo otro combo que se repite no sea el mismo que el que ya cambie, si no me sale otro repetido.. y no es lo q queremos. Aca queria hacerlo con una lista de combos pero no me convence XD ademas deberia hacer una funcion mas 
cambiarLoNecesario :: Pedido -> Pedido -> [Bebida] -> [Hamburguesa] -> Pedido -> [Combo] -> Combo
cambiarLoNecesario ped ped2 [] (h:hs) pedido combosAgregados = cambiarLoNecesario ped ped2 [] (h:hs) pedido combosAgregados
cambiarLoNecesario (AgregarCombo c1 p1) ped2 (b:bs) (h:hs) pedido combosAgregados
	|(seRepiteC (cambiarBebida c1 b) pedido) || elem c1 combosAgregados = cambiarLoNecesario (AgregarCombo c1 p1) ped2 bs (h:hs) pedido combosAgregados
	|otherwise = cambiarBebida c1 b
cambiarLoNecesario ped (AgregarCombo c2 p2) [] (h:hs) pedido
	|(seRepiteC (cambiarSanguche c2 h) pedido) || elem c1 combosAgregados = cambiarLoNecesario ped (AgregarCombo c2 p2) [] hs pedido
	|otherwise = cambiarSanguche c2 h


-}
--Aux		
--cambiarPedido :: Pedido -> Pedido
--cambiarPedido (P n e) = P n e
--cambiarPedido (AgregarCombo c p) = agregarComboP p (comboCambiado c p)
--			|seRepiteC c p = agregarComboP p (comboCambiado c p)
--			|otherwise = AgregarCombo c (cambiarPedido p)

--Aux			
--comboCambiado :: Combo -> Pedido -> Combo
--comboCambiado combo p = cambiarSandwichC combo (sangucheDistinto (sandwichC combo) (sanguchesDelPedido p) )	

--sangucheDistinto :: Hamburguesa -> [Hamburguesa] -> Hamburguesa
--sangucheDistinto h (s:sh) 
--		|h /= s = s
--		|otherwise = sangucheDistinto h sh	


--Pedido de prueba AgregarCombo  (nuevoC Pesticola McGyver 45) (P 1 "Pepe") 

-- (AgregarCombo (nuevoC Pesticola McPato 1) (AgregarCombo (nuevoC Pesticola McGyver 2) (AgregarCombo (nuevoC Pesticola McGyver 3) (AgregarCombo (nuevoC AguaConGags McPato 4) (P 11 "A")))))


--combosP (cambiarBebidaComboP (anularComboP (agregarComboP (agregarComboP (nuevoP 1 "Juan" [(nuevoC Pesticola McGyver 45),(nuevoC FalsaNaranja McPato 55)]) (nuevoC Pesticola McPato 33)) (nuevoC FalsaNaranja McGyver 22)) 1) FalsaNaranja 0) 


--, agregarComboP, anularComboP, cambiarBebidaComboP, elMezcladitoP
